/**
 * WebSocket 客户端类
 * 用于与 crmeb-client 后端进行 WebSocket 通信
 */
class WebSocketClient {
    constructor(url, token = null) {
        this.baseUrl = url;
        this.token = token;
        this.url = url; // 不再在URL中添加token
        this.ws = null;
        this.isConnected = false;
        this.messageHandlers = new Map();
        this.connectionHandlers = [];
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 5;
        this.reconnectInterval = 3000; // 3秒
    }

    /**
     * 设置token
     * @param {string} token 认证token
     */
    setToken(token) {
        this.token = token;
    }

    /**
     * 创建带自定义请求头的WebSocket连接
     * @param {string} url WebSocket URL
     * @param {string} token 认证token
     * @returns {WebSocket} WebSocket实例
     */
    createWebSocketWithHeaders(url, token) {
        // 注意：原生WebSocket不支持自定义请求头
        // 这里提供一个兼容方案，优先使用URL参数，同时支持请求头
        if (token) {
            // 在URL中添加token参数作为备选方案
            const separator = url.includes('?') ? '&' : '?';
            url = `${url}${separator}token=${token}`;
        }
        
        return new WebSocket(url);
    }

    /**
     * 连接 WebSocket
     * @param {Function} onOpen 连接成功回调
     * @param {Function} onClose 连接关闭回调
     * @param {Function} onError 连接错误回调
     */
    connect(onOpen, onClose, onError) {
        try {
            // 使用自定义方法创建WebSocket连接
            this.ws = this.createWebSocketWithHeaders(this.url, this.token);
            
            this.ws.onopen = (event) => {
                this.isConnected = true;
                this.reconnectAttempts = 0;
                console.log('WebSocket 连接已建立');
                if (onOpen) onOpen(event);
                this.notifyConnectionHandlers('open', event);
            };
            
            this.ws.onmessage = (event) => {
                console.log('收到消息:', event.data);
                this.handleMessage(event.data);
            };
            
            this.ws.onclose = (event) => {
                this.isConnected = false;
                console.log('WebSocket 连接已关闭');
                if (onClose) onClose(event);
                this.notifyConnectionHandlers('close', event);
                
                // 自动重连
                if (this.reconnectAttempts < this.maxReconnectAttempts) {
                    this.reconnectAttempts++;
                    console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);
                    setTimeout(() => this.connect(onOpen, onClose, onError), this.reconnectInterval);
                }
            };
            
            this.ws.onerror = (error) => {
                console.error('WebSocket 错误:', error);
                if (onError) onError(error);
                this.notifyConnectionHandlers('error', error);
            };
            
        } catch (error) {
            console.error('连接失败:', error);
            if (onError) onError(error);
        }
    }

    /**
     * 断开连接
     */
    disconnect() {
        if (this.ws) {
            this.ws.close();
            this.ws = null;
            this.isConnected = false;
        }
    }

    /**
     * 发送消息
     * @param {string} action 操作类型
     * @param {Object} data 消息数据
     * @returns {boolean} 是否发送成功
     */
    async sendMessage(action, data) {
        if (action === 'sendMessage') {
            // 流式fetch testAIRes接口
            try {
                const response = await fetch('/api/client/message/testAIRes');
                if (!response.body) return false;
                const reader = response.body.getReader();
                const decoder = new TextDecoder('utf-8');
                let { value, done } = await reader.read();
                let buffer = '';
                while (!done) {
                    buffer += decoder.decode(value, { stream: true });
                    let lines = buffer.split('\n');
                    buffer = lines.pop(); // 最后一行可能不完整，留到下次
                    for (let line of lines) {
                        if (line.trim()) this.handleMessage(line);
                    }
                    ({ value, done } = await reader.read());
                }
                // 处理最后残留内容
                if (buffer.trim()) this.handleMessage(buffer);
                return true;
            } catch (e) {
                console.error('流式获取AI内容失败:', e);
                return false;
            }
        } else {
            if (!this.isConnected || !this.ws) {
                console.error('WebSocket 未连接');
                return false;
            }
            const message = {
                action: action,
                data: data
            };
            try {
                this.ws.send(JSON.stringify(message));
                console.log('发送消息:', message);
                return true;
            } catch (error) {
                console.error('发送消息失败:', error);
                return false;
            }
        }
    }

    /**
     * 处理接收到的消息
     * @param {string} data 消息数据
     */
    handleMessage(data) {
        try {
            const message = JSON.parse(data);
            const handler = this.messageHandlers.get(message.action);
            if (handler) {
                handler(message.data);
            } else {
                console.warn('未找到消息处理器:', message.action);
            }
        } catch (error) {
            // 非JSON消息（如流式输出）
            console.log('收到文本消息:', data);
            const handler = this.messageHandlers.get('text');
            if (handler) {
                handler(data);
            }
        }
    }

    /**
     * 注册消息处理器
     * @param {string} action 操作类型
     * @param {Function} handler 处理函数
     */
    onMessage(action, handler) {
        this.messageHandlers.set(action, handler);
    }

    /**
     * 注册连接状态处理器
     * @param {Function} handler 处理函数
     */
    onConnection(handler) {
        this.connectionHandlers.push(handler);
    }

    /**
     * 通知连接状态处理器
     * @param {string} type 状态类型
     * @param {Object} data 状态数据
     */
    notifyConnectionHandlers(type, data) {
        this.connectionHandlers.forEach(handler => {
            try {
                handler(type, data);
            } catch (error) {
                console.error('连接状态处理器错误:', error);
            }
        });
    }

    /**
     * 获取连接状态
     * @returns {boolean} 是否已连接
     */
    getConnectionStatus() {
        return this.isConnected;
    }
}

/**
 * 消息服务类
 * 封装具体的消息操作
 */
class MessageService {
    constructor(wsClient) {
        this.wsClient = wsClient;
    }

    /**
     * 发送消息
     * @param {Object} params 消息参数
     * @returns {boolean} 是否发送成功
     */
    sendMessage(params) {
        const { dialogId, type, content, members } = params;
        
        if (!content || !content.trim()) {
            console.error('消息内容不能为空');
            return false;
        }
        
        const data = {
            dialogId: dialogId ? parseInt(dialogId) : null,
            type: parseInt(type) || 1,
            content: content.trim(),
            members: members ? members.split(',').map(m => m.trim()) : []
            // 注意：userId 现在从 WebSocket 会话中获取，不需要前端传递
        };
        
        return this.wsClient.sendMessage('sendMessage', data);
    }

    /**
     * 获取消息列表
     * @param {number} dialogId 对话框ID
     * @param {number} page 页码
     * @param {number} pageSize 每页大小
     * @returns {boolean} 是否发送成功
     */
    getMessageList(dialogId, page = 1, pageSize = 20) {
        if (!dialogId) {
            console.error('对话框ID不能为空');
            return false;
        }
        
        const data = {
            dialogId: parseInt(dialogId),
            page: parseInt(page),
            pagesize: parseInt(pageSize)
        };
        
        return this.wsClient.sendMessage('getMessageList', data);
    }

    /**
     * 获取对话框列表
     * @returns {boolean} 是否发送成功
     */
    getDialogList() {
        // 注意：userId 现在从 WebSocket 会话中获取，不需要前端传递
        const data = {};
        
        return this.wsClient.sendMessage('getDialogList', data);
    }

    /**
     * 删除对话框
     * @param {number} dialogId 对话框ID
     * @returns {boolean} 是否发送成功
     */
    deleteDialog(dialogId) {
        if (!dialogId) {
            console.error('对话框ID不能为空');
            return false;
        }
        
        const data = {
            dialogId: parseInt(dialogId)
        };
        
        return this.wsClient.sendMessage('delDialog', data);
    }

    /**
     * 测试流式输出
     * @returns {boolean} 是否发送成功
     */
    testStream() {
        return this.wsClient.sendMessage('testStream', {});
    }
}

// 导出类
if (typeof module !== 'undefined' && module.exports) {
    module.exports = { WebSocketClient, MessageService };
} 